﻿using System.IO;
using System.Collections.Generic;
using System;
using UnityEngine;
namespace CommonLib.Save
{
	using SaveExtension;
	public class BinaryBuffer : BinaryIODictionary<IBinaryIO>
	{

	}


	/// <summary>
	/// 对于一组 继承了IBinaryIO的保存信息数据的管理
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class BinaryIODictionary<T>
		where T : IBinaryIO
	{
		public Dictionary<string, byte[]> Buffers => buffers;
		Dictionary<string, byte[]> buffers = new Dictionary<string, byte[]>();

		public bool IsInit => Buffers.Count > 0;

		/// <summary>
		/// 将列表中实际数据类的数据跟新持有字典，并将其数据写入二进制流
		/// </summary>
		/// <param name="writer">二进制写入流</param>
		/// <param name="ioList">继承IBinaryIO的实际数据类</param>
		static public void Write(BinaryWriter writer, List<T> ioList)
		{
			BinaryIODictionary<T> bufferList = new BinaryIODictionary<T>();
			bufferList.MakeBuffer(ioList);
			try
			{
				bufferList.Write(writer);
			}
			catch(Exception e)
			{
				Debug.LogError("数据流写入出现问题！");
				throw new Exception(e.StackTrace); 
			}

		}

		/// <summary>
		/// 将二进制流的数据读取出来保存更新持有字典，并将数据重载到实际数据类
		/// </summary>
		/// <param name="reader">二进制读取流</param>
		/// <param name="ioList">继承IBinaryIO的实际数据类</param>
		static public void Read(BinaryReader reader, List<T> ioList)
		{
			BinaryIODictionary<T> bufferList = new BinaryIODictionary<T>();
			try
			{
				bufferList.Read(reader);
			}
			catch(Exception e)
			{
				Debug.LogError("数据流读出出现问题！");
				throw new Exception(e.StackTrace); 
			}
			bufferList.Overrirde(ioList);
		}


		/// <summary>
		/// 将实际数据类写入持有的BufferList中
		/// </summary>
		/// <param name="ioList"></param>
		public void MakeBuffer(List<T> ioList)
		{
			Buffers.Clear();
			UnityEngine.Profiling.Profiler.BeginSample("数据类生成数据");
			//提取每一个数据保存类的数据
			for (int index = 0; index < ioList.Count; index++)
			{
				var entry = ioList[index];
				if (!Buffers.ContainsKey(entry.SaveKey))
				{
					byte[] tempBuffer = BinaryUtil.BinaryWrite(entry.WriteSaveData);
					Buffers.Add(entry.SaveKey, tempBuffer);
				}
				else
				{
					Debug.LogError("将重复的数据类（IBinaryIO）写入缓存Buffer");
				}
			}
			UnityEngine.Profiling.Profiler.EndSample();
		}

		public void Overrirde(List<T> ioList)
		{
			UnityEngine.Profiling.Profiler.BeginSample("恢复数据类");
			//将缓存数据恢复给实体数据类
			for (int index = 0; index < ioList.Count; index++)
			{
				var entry = ioList[index];
				if (Buffers.ContainsKey(entry.SaveKey))
				{
					BinaryUtil.BinaryRead(buffers[entry.SaveKey], entry.ReadSaveData);
				}
				else
				{
					Debug.LogError("读取缓存Buffer中不存在的数据类");
				}
			}
			UnityEngine.Profiling.Profiler.EndSample();
		}


		/// <summary>
		/// 写入所有缓存
		/// </summary>
		/// <param name="writer"></param>
		public void Write(BinaryWriter writer)
		{
			writer.Write(Buffers.Count);
			foreach (var bf in Buffers)
			{
				writer.Write(bf.Key);
				writer.WriteBuffer(bf.Value);
			}

		}

		/// <summary>
		/// 读出所有缓存
		/// </summary>
		/// <param name="reader"></param>
		public void Read(BinaryReader reader)
		{
			Buffers.Clear();
			int Length = reader.ReadInt32();
			for (int i = 0; i < Length; i++)
			{
				var key = reader.ReadString();
				var buffer = reader.ReadBuffer();
				Buffers.Add(key, buffer);
			}
		}
	}
}